﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using System.Xml.Linq;
using WpfApp1.bean;
using WpfApp1.Main;

/**我的串口同信处理*/
namespace WpfApp1.CMD
{
    class myCom : ComModelInterface
    {
        // 累加和（SUM = CMD + ADDR + NUM + DATA + ETX）
        private string SUM = string.Empty;
        // 地址值（对于D区地址小于8000的计算公式 ADDR = 1000H + ADDR*2）
        private string ADDR = string.Empty;
        // 开始字符
        private string STX = "02";

        // 结束字符
        private string ETX = "03";

        // 命令码
        private string CMD = "31";

        // 字节数（现在使用4个字节对应的ASCII码值是3034）
        private string NUM = "3034";

        // 发送的数据（先转成16进制再低字节在前高字节在后）
        private string DATA = string.Empty;
        /// PLC地址
        public string PLC_add = "10";


        /**连接指示灯串口*/
        SerialPort PlcSerialPort;
        /**连接扫描枪串口*/
        SerialPort ScanSerialPort;
        /**扫描枪串口名*/
        chuankoubean COM_Scrn = new chuankoubean();
        /**指示灯串口名*/
        chuankoubean COM_Deng = new chuankoubean();

        MainInterface M;

        /**扫描串口连接状态*/
        Boolean ischuankou = false;
        /**指示灯串口连接状态*/
        Boolean isdeng = false;
        /**初始化类*/
        public myCom(MainInterface mainInterface)
        {
            this.M = mainInterface;
        }
        
        /**初始化串口*/
        public void InitCOM()
        {
            String[] chuankous = SerialPort.GetPortNames();
            Console.WriteLine(chuankous.Length);
            if (chuankous.Length > 0)
            {
                //ScanSerialPort = new SerialPort(COM_Scrn.portName, 115200, Parity.None, 8, StopBits.One);
                ScanSerialPort = new SerialPort(COM_Scrn.portName, COM_Scrn.baudRate, getparity(COM_Scrn.parity), COM_Scrn.dataBits, getstopBits(COM_Scrn.stopBits));
                ScanSerialPort.DataBits = 8;
                ScanSerialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_pan1_DataReceived);
                ischuankou = OpenPort(ScanSerialPort);//串口打开

                //PlcSerialPort = new SerialPort(COM_Deng.portName, 9600, Parity.Odd, 7, StopBits.One);
                PlcSerialPort = new SerialPort(COM_Deng.portName, COM_Deng.baudRate, getparity(COM_Deng.parity), COM_Deng.dataBits, getstopBits(COM_Deng.stopBits));
                isdeng = OpenPort(PlcSerialPort);//串口打开
            }
            else
            {
                MessageBox.Show("未检测到有连接的扫描枪，无法扫描");
            }

        }

        /**获取校验位*/
        public Parity getparity(String parity)
        {
            if (parity == "NONE")
            {
                return Parity.None;
            }
            if (parity == "ODD")
            {
                return Parity.Odd;
            }
            if (parity == "EVEN")
            {
                return Parity.Even;
            }
            return Parity.None;
        }

        /**获取停止位*/
        public StopBits getstopBits(String stopBits)
        {
            if (stopBits == "NONE")
            {
                return StopBits.None;
            }
            if (stopBits == "ONE")
            {
                return StopBits.One;
            }
            if (stopBits == "TWO")
            {
                return StopBits.Two;
            }
            return StopBits.None;
        }

        /**打开串口的方法*/
        public bool OpenPort(SerialPort serialPort)
        {
            try//这里写成异常处理的形式以免串口打不开程序崩溃
            {
                serialPort.Open();
            }
            catch { }
            if (serialPort.IsOpen)
            {
                
                //MessageBox.Show("串口打开成功!");
                return true;
            }
            else
            {
                MessageBox.Show("串口打开失败!");
                return false;
            }
        }

        /**扫描枪扫描到后返回*/
        private void serialPort_pan1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(200);
            var s = ScanSerialPort.ReadExisting();
            M.scrm_com(s);
        }

        /**获取设置的串口和刷新串口*/
        public void readCOMs(Boolean ischongqi)
        {
            string filePath = MainWindow.path + "save\\com_setting.xml";
            if (File.Exists(filePath))
            {
                XElement xmlDoc = XElement.Load(filePath);
                COM_Scrn.portName = xmlDoc.Attribute("sao_portName").Value;
                COM_Deng.portName = xmlDoc.Attribute("deng_portName").Value;

                COM_Scrn.baudRate = int.Parse(xmlDoc.Attribute("sao_baudRate").Value);
                COM_Deng.baudRate = int.Parse(xmlDoc.Attribute("deng_baudRate").Value);

                COM_Scrn.parity = xmlDoc.Attribute("sao_parity").Value;
                COM_Deng.parity = xmlDoc.Attribute("deng_parity").Value;

                COM_Scrn.dataBits = int.Parse(xmlDoc.Attribute("sao_dataBits").Value);
                COM_Deng.dataBits = int.Parse(xmlDoc.Attribute("deng_dataBits").Value);

                COM_Scrn.stopBits = xmlDoc.Attribute("sao_stopBits").Value;
                COM_Deng.stopBits = xmlDoc.Attribute("deng_stopBits").Value;

                if (ischongqi)
                {
                    if (PlcSerialPort != null)
                    {
                        isdeng = false;
                        PlcSerialPort.Close();
                    }
                    if (ScanSerialPort != null)
                    {
                        ischuankou = false;
                        ScanSerialPort.Close();
                    }
                    InitCOM();
                }
            }
        }


        /**获取命令字符串*/
        private string get_cmd_str(int id_value)
        {
            string cmd_str = string.Empty;
            SUM = "";

            ADDR = Convert.ToString((Convert.ToInt32(PLC_add) * 2) + Convert.ToInt32("1000", 16), 16);//地址值计算

            ADDR = ADDR.ToUpper();
            //lemp_no = 
            //十进制累加和
            int sum_int = 0;

            string addr_asc = string.Empty;

            sum_int = Convert.ToInt32(CMD, 16);

            for (int i = 0; i < ADDR.Length; i++)
            {
                sum_int += (int)ADDR[i];

                addr_asc += Convert.ToString((int)ADDR[i], 16);
            }

            for (int i = 0; i < NUM.Length / 2; i++)
            {
                sum_int += Convert.ToInt32(NUM.Substring(i * 2, 2), 16);
            }

            //发送数据处理
            string temp = string.Empty;

            temp = Convert.ToString(id_value, 16);


            temp = temp.ToString().PadLeft(4, '0');

            temp = temp.ToUpper();//转换成大写字母

            string[] str = new string[4];
            for (int i = 0; i < temp.Length; i++)
            {
                sum_int += (int)temp[i];

                str[i] = Convert.ToString((int)temp[i], 16);
            }

            DATA = str[2] + str[3] + str[0] + str[1];//数据按低字节在前高字节在后

            sum_int += Convert.ToInt32(ETX, 16);

            string sum_str = Convert.ToString(sum_int, 16).ToUpper();//转成十六进制再将字母转换成大写

            if (sum_str.Length > 2)
            {
                sum_str = sum_str.Substring(1, 2);
            }

            for (int i = 0; i < sum_str.Length; i++)
            {
                SUM += Convert.ToString((int)sum_str[i], 16);//获取累加和
            }

            return cmd_str = STX + CMD + addr_asc + NUM + DATA + ETX + SUM;
            //MessageBox.Show(cmd_str);
        }

        /**发送命令*/
        private void out_cmd(string cmd_str)
        {
            Console.WriteLine(cmd_str);
            //MessageBox.Show(cmd_str);
            int n = cmd_str.Length / 2;
            byte[] data = new byte[n];
            for (int i = 0; i < n; i++)
            {
                data[i] = Convert.ToByte(cmd_str.Substring(2 * i, 2), 16);//转成字节型
            }
            if (data.Length == 0)
            {
                MessageBox.Show("输入字符无效", "提示");
                return;
            }

            try
            {
                PlcSerialPort.Write(data, 0, data.Length);
            }
            catch (Exception ep)
            {
                MessageBox.Show("发送失败！" + ep.Message + ep.StackTrace, "提示");
            }

        }

        /**发送关闭指示灯命令*/
        private void close_cmd(string cmd_str)
        {

            int n = cmd_str.Length / 2;
            byte[] data = new byte[n];
            for (int i = 0; i < n; i++)
            {
                data[i] = Convert.ToByte(cmd_str.Substring(2 * i, 2), 16);//转成字节型
            }
            if (data.Length == 0)
            {
                MessageBox.Show("输入字符无效", "提示");
                return;
            }

            try
            {
                PlcSerialPort.Write(data, 0, data.Length);
            }
            catch (Exception)
            {
                MessageBox.Show("发送失败！", "提示");
            }
        }

        /**亮绿灯*/
        public void greenLight(int id_value)
        {
            Console.WriteLine(id_value);
            string cmd_str = string.Empty;
            PLC_add = ((id_value - 1) * 5 + 510).ToString();
            cmd_str = get_cmd_str(id_value);
            out_cmd(cmd_str);
        }
        /**亮红灯*/
        public void redLight(int id_value)
        {
            string cmd_str = string.Empty;
            PLC_add = "10";
            cmd_str = get_cmd_str(id_value);
            out_cmd(cmd_str);
        }
        /**熄灭灯*/
        public void mieLight(int id_value)
        {
            if (id_value == 0)
            {
                PLC_add = "10";
            }
            else
            {
                PLC_add = ((id_value - 1) * 5 + 510).ToString();
            }
            string cmd_str = string.Empty;
            cmd_str = get_cmd_str(0);
            Console.WriteLine("id_value===" + cmd_str);
            close_cmd(cmd_str);
        }
        /**包放入托盘*/
        public void RedLight(int id_value)
        {
            if (!isdeng)
            {
                return;
            }
            redLight(id_value);
            Thread.Sleep(200);
            mieLight(id_value);
        }
        /**组盘上传完成*/
        public void GreenLight(int id_value)
        {
            if (!isdeng)
            {
                return;
            }
            redLight(id_value);
            Thread.Sleep(200);
            greenLight(id_value);
        }

        int zu_deng = 0;
        /**扫描缓冲仓位，绑盘*/
        public void BangpanLight(int id_value)
        {
            if (!isdeng)
            {
                return;
            }
            //redLight(0);
            //Thread.Sleep(200);
            //mieLight(id_value);
            //redLight(id_value);
            //Thread.Sleep(100);
            if (zu_deng != 0)
            {
                mieLight(zu_deng);
                Thread.Sleep(200);
            }
            zu_deng = id_value;
            greenLight(id_value);

        }

        public void quenchLight(int id_value)
        {
            //if (!isdeng)
            //{
            //    return;
            //}
            Console.WriteLine("id_value===" + id_value);

            zu_deng = 0;
            mieLight(id_value);
        }

        public void miehong()
        {
            mieLight(0);
            Thread.Sleep(200);
        }
    }
}
